<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>prototype</title>
  </head>
  <body></body>
  <script>
    var A = function() {}; // 新建一个A函数
    console.log(A.prototype);
    var f1 = new A();
    console.log(f1);
    console.log(f1.__proto__);
    /*
    打印出一个对象
    {
        constructor:fn()
        __proto__...
    }
    1.__proto__和constructor属性是对象所独有的；
    2.prototype属性是函数所独有的。
    但是由于JS中函数也是一种对象，所以函数也拥有__proto__和constructor属性
    */
    /*
    1.__proto__属性:
      是对象所独有的，都是由一个对象指向另外一个对象，即指向它们的原型对象（也可以理解为父对象）
      作用：当访问一个对象的属性时，如果该对象内部不存在该属性，那么就会去它的__proto__属性所指向的那个对象（父亲对象）中去找，直到找到原型链顶端null，此时如果还没找到，则返回undefined
      由以上这种通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链
    2.prototype属性：
      是函数所独有的，从一个函数指向一个对象；
      含义是函数的原型对象，也就是这个函数（其实所有的函数都可以作为构造函数）所创建的实例的原型对象
      所以f1.__proto__ === A.prototype，它们两个完全一样
      作用：包含可以由特定类型的所有实例共享的属性和方法，也就是让该函数所实例化的对象们都可以找到公用的属性和方法。
    3.constructor属性：
      是对象才拥有的，从一个对象指向一个函数；
      含义是指向该对象的构造函数，每个对象都有构造函数，
      Function这个对象比较特殊，它的构造函数就是它自己（因为Function可以看成是一个函数，也可以是一个对象），所有函数最终都是由Function()构造函数得来，所以constructor属性的终点就是Function()
    */
    // 木易杨
    function Parent(age) {
      this.age = age;
    }
    //instanceof运算符用来检测constructor.prototype是否存在于参数object的原型链上。
    var p = new Parent(50);
    console.log(p.constructor)
    console.log(Parent === Object) // false
    console.log(Parent instanceof Object) // true Parent在不在Object构造函数中
    console.log(p.constructor instanceof Object) // true
    p.constructor === Parent; // true function的构造函数指向自己
    p.constructor === Object; // false
    Parent.prototype.speck =function(){
        console.log("哈哈哈哈")
    }
    console.log(Parent.prototype.__proto__)
    var tell = new Parent(20)
    console.log(Parent.prototype)
    tell.speck() // 哈哈哈哈

    function A(){}
    function B(a){
      this.a=a;
    }
    function C(a){
      if(a){
        this.a=a
      }
    }
    A.prototype.a=1;
    B.prototype.a=1;
    C.prototype.a=1;
    console.log(new A().a)//1 原型链上的1
    console.log(new B()) //  {a: undefined}
    console.log(new B().a)//undefined
    console.log(new C(2).a)//2
  </script>
</html>
